package net

import (
	"context"
	"fmt"
	"os"
	"os/signal"

	mqtt "github.com/eclipse/paho.mqtt.golang"
)

func NewMqtt(ctx context.Context, endpoint string) *Mqtt {
	r := &Mqtt{
		ctx:      ctx,
		endpoint: endpoint,
		topic:    "default",
	}

	return r
}

type Mqtt struct {
	ctx      context.Context
	endpoint string
	topic    string
	clientId string
	qos      byte
	retained bool

	options *mqtt.ClientOptions
	client  mqtt.Client
}

func (r *Mqtt) Endpoint(endpoint string) *Mqtt {
	r.endpoint = endpoint

	return r
}
func (r *Mqtt) Topic(topic string) *Mqtt {
	r.topic = topic

	return r
}
func (r *Mqtt) ClientId(clientId string) *Mqtt {
	r.clientId = clientId

	return r
}
func (r *Mqtt) Qos(qos byte) *Mqtt {
	r.qos = qos

	return r
}
func (r *Mqtt) Retained(retained bool) *Mqtt {
	r.retained = retained

	return r
}

func (r *Mqtt) Connect() *Mqtt {
	r.options = mqtt.NewClientOptions()
	r.options.AddBroker(r.endpoint)
	r.options.SetClientID(r.clientId)

	r.client = mqtt.NewClient(r.options)

	token := r.client.Connect()
	if token.Wait() && token.Error() != nil {
		panic(token.Error())
	}

	return r
}
func (r *Mqtt) Subscribe() {
	token := r.client.Subscribe(r.topic, r.qos, func(client mqtt.Client, msg mqtt.Message) {
		fmt.Printf("Received message on topic %s: %s\n", msg.Topic(), msg.Payload())
	})
	if token.Wait() && token.Error() != nil {
		panic(token.Error())
	}

	c := make(chan os.Signal, 1)
	signal.Notify(c, os.Interrupt, os.Kill)
	<-c

	r.client.Disconnect(250)
}
func (r *Mqtt) Publish(payload interface{}) {
	token := r.client.Publish(r.topic, r.qos, r.retained, payload)
	token.Wait()
}
